"""
规格识别增强模块
增强从商品名称中提取规格和单位的能力
"""
import re
import logging
from typing import Dict, List, Tuple, Optional
import pandas as pd

# 创建日志记录器
logger = logging.getLogger(__name__)

class SpecificationExtractor:
    """商品规格提取器类"""
    
    def __init__(self, units_list: List[str], unit_conversion: Dict = None, standard_unit_map: Dict = None):
        """
        初始化规格提取器
        
        Args:
            units_list: 单位列表
            unit_conversion: 单位转换规则，格式为 {源单位: 转换函数}
            standard_unit_map: 标准单位映射，格式为 {源单位: 标准单位}
        """
        # 确保关键单位在列表中
        basic_units = ["g", "kg", "斤", "L", "l", "升", "ml", "毫升", "盒", "瓶", "袋", "箱", "个", "件", "罐", "桶", "支", "条", "包"]
        self.units = list(set(units_list + basic_units))
        
        # 初始化单位转换和映射，确保L/l在里面
        self.unit_conversion = unit_conversion or {}
        if 'L' not in self.unit_conversion and 'l' not in self.unit_conversion:
            self.unit_conversion['L'] = lambda x: x
            self.unit_conversion['l'] = lambda x: x
            
        self.standard_unit_map = standard_unit_map or {}
        if 'L' not in self.standard_unit_map and 'l' not in self.standard_unit_map:
            self.standard_unit_map['L'] = '升'
            self.standard_unit_map['l'] = '升'
        
        # 按长度排序单位，避免短单位优先匹配
        self.sorted_units = sorted(self.units, key=len, reverse=True)
        
        # 生成单位正则表达式，确保完整匹配
        self.units_regex = '|'.join(map(re.escape, self.sorted_units))
        
        # 定义单位优先级（用于复合规格）
        self.unit_priority = {
            '箱': 12,   # 提高箱的优先级，使其成为最高优先级
            '瓶': 10, 
            '盒': 9, 
            '袋': 8, 
            '包': 8, 
            '罐': 7, 
            '桶': 7, 
            '件': 6, 
            '个': 6, 
            '支': 6, 
            '根': 6, 
            '条': 6,
            'kg': 5, 
            '千克': 5, 
            '公斤': 5, 
            '斤': 4, 
            'g': 3, 
            '克': 3, 
            'L': 2, 
            'l': 2, 
            '升': 2, 
            '立升': 2,
            'ml': 1, 
            '毫升': 1
        }
        
        # 添加其他单位的默认优先级
        for unit in self.units:
            if unit not in self.unit_priority:
                self.unit_priority[unit] = 0
        
        # 构建规格提取正则表达式
        self._build_regex_patterns()
        
        logger.info(f"规格提取器初始化完成，单位数量：{len(self.units)}")
    
    def _build_regex_patterns(self):
        """构建规格提取的正则表达式模式"""
        
        # 基本数字模式
        number_pattern = r'(\d+(?:\.\d+)?)'
        
        # 1. 标准规格模式 - 数字+单位
        self.standard_spec_pattern = fr'{number_pattern}\s*(?:{self.units_regex})'
        
        # 2. 约数规格模式 - "约"+数字+单位  净重约100g
        # 约数规格模式 - "约"+数字+单位  净重约100g
        self.approx_spec_pattern = fr'(?:净重|重量|规格)?约\s*{number_pattern}\s*(?:{self.units_regex})'
        # self.approx_spec_pattern = fr'约\s*{number_pattern}\s*(?:{self.units_regex})'

        #
        
        # 3. 范围规格模式 - 数字+范围符号+数字+单位
        self.range_spec_pattern = fr'{number_pattern}\s*[-~到至]\s*{number_pattern}\s*(?:{self.units_regex})'
        
        # 4. 复合规格模式 - 数字+单位+分隔符+数字+单位
        # 例如: 500ml*6瓶, 250g/包, 400g*3袋/箱
        self.compound_spec_pattern = fr'{number_pattern}\s*(?:{self.units_regex})\s*[*×x/]\s*{number_pattern}\s*(?:{self.units_regex})'
        
        # 5. 每单位规格 - 数字+单位+"每"+单位
        # 例如: 500ml每瓶, 100g每包
        self.per_unit_spec_pattern = fr'{number_pattern}\s*(?:{self.units_regex})\s*每\s*(?:{self.units_regex})'
        
        # 6. 特殊处理小数点+L的情况，例如：1.8L
        self.special_L_pattern = r'(\d+(?:\.\d+)?)[Ll]'
        
        # 结合所有模式
        self.all_patterns = [
            ('range', self.range_spec_pattern),      # 优先匹配范围规格
            ('compound', self.compound_spec_pattern), # 然后是复合规格
            ('per_unit', self.per_unit_spec_pattern), # 再是每单位规格
            ('approx', self.approx_spec_pattern),    # 然后是约数规格
            ('special_L', self.special_L_pattern),   # 特殊处理L单位
            ('standard', self.standard_spec_pattern)  # 最后是标准规格
        ]
        
        logger.info("规格提取正则表达式构建完成")
    
    def extract_specifications(self, text: str) -> Dict:
        """
        从文本中提取规格信息，优先提取标准包装单位
        
        Args:
            text: 商品名称文本
            
        Returns:
            包含规格信息的字典
        """
        result = {
            'spec_text': '',
            'spec_type': '',
            'spec_value': 0.0,
            'spec_unit': '',
            'secondary_value': 0.0,
            'secondary_unit': '',
            'standard_value': 0.0,
            'standard_unit': '',
            'cleaned_text': text,
            'confidence': 0.0
        }
        
        # 如果文本为空，直接返回
        if not text or not isinstance(text, str) or len(text.strip()) < 2:
            return result
            
        # 预处理：检测"整箱装"、"整袋装"等格式
        if '整箱装' in text or '整箱' in text:
            # 寻找可能的数量*单位格式，例如 "200g*10根"
            quantity_pattern = r'(\d+(?:\.\d+)?)\s*(?:{0})\s*[*×x]\s*(\d+)\s*(?:{1})'.format(
                self.units_regex, '|'.join(map(re.escape, ['根', '个', '支', '条', '瓶', '盒', '袋', '包'])))
            quantity_match = re.search(quantity_pattern, text)
            
            if quantity_match:
                spec_text = quantity_match.group(0) + ' 整箱装'
                # 提取数值和单位
                numbers = re.findall(r'\d+(?:\.\d+)?', quantity_match.group(0))
                
                # 特别处理包含"*X根"这样的格式，直接获取单位
                unit_text = quantity_match.group(0)
                secondary_unit = ''
                for unit in ['根', '个', '支', '条', '瓶', '盒', '袋', '包']:
                    if unit in unit_text:
                        secondary_unit = unit
                        break
                
                # 获取第一部分的单位（如"200g"中的"g"）
                first_unit = ''
                for unit in self.sorted_units:
                    # 确保单位在第一个数字后面，第二个数字之前
                    first_part = unit_text.split('*')[0] if '*' in unit_text else unit_text.split('×')[0] if '×' in unit_text else unit_text.split('x')[0] if 'x' in unit_text else unit_text
                    if unit in first_part:
                        first_unit = unit
                        break
                
                if numbers and (secondary_unit or first_unit):
                    result['spec_text'] = spec_text
                    result['spec_type'] = 'compound'
                    result['spec_value'] = 1.0  # 1箱
                    result['spec_unit'] = '箱'
                    
                    # 设置次要规格信息
                    if len(numbers) >= 2:
                        result['secondary_value'] = float(numbers[0])
                        result['secondary_unit'] = secondary_unit or first_unit
                    else:
                        result['secondary_value'] = float(numbers[0]) if numbers else 0.0
                        result['secondary_unit'] = secondary_unit or first_unit
                    
                    result['confidence'] = 0.95
                    
                    # 清理文本
                    clean_start = text.find(quantity_match.group(0))
                    if clean_start != -1:
                        box_pos = text.find('整箱装', clean_start)
                        if box_pos != -1:
                            box_end = box_pos + 3  # 整箱装的长度
                            result['cleaned_text'] = text[:clean_start] + ' ' + text[box_end:]
                            result['cleaned_text'] = re.sub(r'\s+', ' ', result['cleaned_text']).strip()
                    
                    self._standardize_spec(result)
                    return result
            else:
                # 如果没有找到明确的数量*单位格式，但有"整箱装"
                # 尝试查找单独的重量/数量单位
                simple_pattern = r'(\d+(?:\.\d+)?)\s*(?:{0})'.format(self.units_regex)
                simple_match = re.search(simple_pattern, text)
                
                if simple_match:
                    spec_text = simple_match.group(0) + ' 整箱装'
                    result['spec_text'] = spec_text
                    result['spec_type'] = 'compound'
                    result['spec_value'] = 1.0  # 1箱
                    result['spec_unit'] = '箱'
                    number = float(re.search(r'\d+(?:\.\d+)?', simple_match.group(0)).group(0))
                    unit = self._extract_unit(simple_match.group(0))
                    result['secondary_value'] = number
                    result['secondary_unit'] = unit
                    result['confidence'] = 0.9
                    
                    # 清理文本
                    clean_start = text.find(simple_match.group(0))
                    if clean_start != -1:
                        box_pos = text.find('整箱装', clean_start)
                        if box_pos != -1:
                            box_end = box_pos + 3  # 整箱装的长度
                            result['cleaned_text'] = text[:clean_start] + ' ' + text[box_end:]
                            result['cleaned_text'] = re.sub(r'\s+', ' ', result['cleaned_text']).strip()
                    
                    self._standardize_spec(result)
                    return result
        
        # 识别"Xkg装"、"X克装"等格式为"袋"单位
        package_pattern = r'(\d+(?:\.\d+)?)\s*(?:kg|千克|克|g|斤)\s*装'
        package_match = re.search(package_pattern, text)
        if package_match:
            spec_text = package_match.group(0)
            weight = float(re.search(r'\d+(?:\.\d+)?', spec_text).group(0))
            weight_unit = self._extract_unit(spec_text)
            
            result['spec_text'] = spec_text
            result['spec_type'] = 'standard'
            result['spec_value'] = weight
            result['spec_unit'] = weight_unit
            # 根据业务需求，"X kg装"默认视为"袋"
            result['secondary_value'] = 1.0
            result['secondary_unit'] = '袋'
            result['confidence'] = 0.9
            
            # 清理文本
            result['cleaned_text'] = text.replace(spec_text, '')
            result['cleaned_text'] = re.sub(r'\s+', ' ', result['cleaned_text']).strip()
            
            self._standardize_spec(result)
            return result
            
        # 预处理：检测是否有"盒/箱"或"*/箱"格式，并确保能够被正确识别
        if '箱' in text:
            # 专门匹配"数字+单位*/箱"和"数字+单位/箱"这种格式
            box_pattern = rf'(\d+(?:\.\d+)?)\s*(?:{self.units_regex})\s*[*×x/]\s*(\d+(?:\.\d+)?)\s*(?:{self.units_regex})\s*/\s*箱'
            box_match = re.search(box_pattern, text)
            if box_match:
                spec_text = box_match.group(0)
                self._process_match(box_match, spec_text, 'compound', result)
                result['cleaned_text'] = text[:box_match.start()] + ' ' + text[box_match.end():]
                result['cleaned_text'] = re.sub(r'\s+', ' ', result['cleaned_text']).strip()
                self._standardize_spec(result)
                # 确保箱是主单位
                if result['spec_unit'] != '箱' and '箱' in spec_text:
                    # 交换主次单位
                    temp_value = result['spec_value']
                    temp_unit = result['spec_unit']
                    result['spec_value'] = result['secondary_value'] if result['secondary_value'] > 0 else 1.0
                    result['spec_unit'] = '箱'
                    result['secondary_value'] = temp_value
                    result['secondary_unit'] = temp_unit
                    logger.info(f"将箱设为主单位: {spec_text}")
                return result
                
            # 匹配"数字+单位/箱"格式（没有中间数量的情况）
            simple_box_pattern = rf'(\d+(?:\.\d+)?)\s*(?:{self.units_regex})\s*/\s*箱'
            simple_box_match = re.search(simple_box_pattern, text)
            if simple_box_match:
                spec_text = simple_box_match.group(0)
                value_match = re.search(r'\d+(?:\.\d+)?', spec_text)
                if value_match:
                    number = float(value_match.group(0))
                    unit = self._extract_unit(spec_text.split('/')[0])
                    
                    result['spec_text'] = spec_text
                    result['spec_type'] = 'compound'
                    result['spec_value'] = 1.0  # 默认1箱
                    result['spec_unit'] = '箱'
                    result['secondary_value'] = number
                    result['secondary_unit'] = unit
                    result['confidence'] = 0.95
                    
                    result['cleaned_text'] = text[:simple_box_match.start()] + ' ' + text[simple_box_match.end():]
                    result['cleaned_text'] = re.sub(r'\s+', ' ', result['cleaned_text']).strip()
                    self._standardize_spec(result)
                    return result
                    
            # 匹配"数字+单位*数字+箱"格式
            box_multiply_pattern = rf'(\d+(?:\.\d+)?)\s*(?:{self.units_regex})\s*[*×x]\s*(\d+(?:\.\d+)?)\s*箱'
            box_multiply_match = re.search(box_multiply_pattern, text)
            if box_multiply_match:
                spec_text = box_multiply_match.group(0)
                numbers = re.findall(r'\d+(?:\.\d+)?', spec_text)
                if len(numbers) >= 2:
                    # 提取第一部分的单位（在分隔符前面）
                    first_part = re.split(r'[*×x]', spec_text)[0]
                    first_unit = self._extract_unit(first_part)
                    
                    result['spec_text'] = spec_text
                    result['spec_type'] = 'compound'
                    result['spec_value'] = float(numbers[1])  # 箱数
                    result['spec_unit'] = '箱'
                    result['secondary_value'] = float(numbers[0])
                    result['secondary_unit'] = first_unit
                    result['confidence'] = 0.95
                    
                    result['cleaned_text'] = text[:box_multiply_match.start()] + ' ' + text[box_multiply_match.end():]
                    result['cleaned_text'] = re.sub(r'\s+', ' ', result['cleaned_text']).strip()
                    self._standardize_spec(result)
                    return result
            
        # 特殊处理：直接匹配1.8L这种格式
        l_match = re.search(r'(\d+(?:\.\d+)?)[Ll](?!\w)', text)
        if l_match:
            spec_text = l_match.group(0)
            number = float(l_match.group(1))
            result['spec_text'] = spec_text
            result['spec_type'] = 'special_L'
            result['spec_value'] = number
            result['spec_unit'] = 'L'
            result['confidence'] = 0.95
            result['cleaned_text'] = text[:l_match.start()] + ' ' + text[l_match.end():]
            result['cleaned_text'] = re.sub(r'\s+', ' ', result['cleaned_text']).strip()
            self._standardize_spec(result)
            return result
            
        # 优先级排序的单位分组
        standard_packaging_units = ['箱', '袋', '瓶', '包', '盒', '罐', '桶', '件', '个', '支', '根', '条']
        measurement_units = ['kg', 'g', 'L', 'l', 'ml', '千克', '公斤', '克', '升', '毫升', '斤']
        
        # 1. 先尝试查找标准包装单位
        for unit in standard_packaging_units:
            if unit in text:
                # 构建针对特定单位的模式
                for pattern_type, pattern_template in [
                    ('compound', rf'\d+(?:\.\d+)?\s*(?:{self.units_regex})\s*[*×x/]\s*\d+(?:\.\d+)?\s*(?:{unit})'),  # 修改模式顺序
                    ('compound', rf'\d+(?:\.\d+)?\s*(?:{unit})\s*[*×x/]\s*\d+(?:\.\d+)?\s*(?:{self.units_regex})'),
                    ('standard', rf'\d+(?:\.\d+)?\s*(?:{unit})'),
                    ('approx', rf'约\s*\d+(?:\.\d+)?\s*(?:{unit})')
                ]:
                    match = re.search(pattern_template, text)
                    if match:
                        spec_text = match.group(0)
                        self._process_match(match, spec_text, pattern_type, result)
                        result['cleaned_text'] = text[:match.start()] + ' ' + text[match.end():]
                        result['cleaned_text'] = re.sub(r'\s+', ' ', result['cleaned_text']).strip()
                        self._standardize_spec(result)
                        return result
                        
        # 2. 如果没有找到标准包装单位，再尝试查找测量单位
        for unit in measurement_units:
            if unit in text:
                # 构建针对特定单位的模式
                for pattern_type, pattern_template in [
                    ('compound', rf'\d+(?:\.\d+)?\s*(?:{unit})\s*[*×x/]\s*\d+(?:\.\d+)?\s*(?:{self.units_regex})'),
                    ('standard', rf'\d+(?:\.\d+)?\s*(?:{unit})'),
                    ('approx', rf'约\s*\d+(?:\.\d+)?\s*(?:{unit})')
                ]:
                    match = re.search(pattern_template, text)
                    if match:
                        spec_text = match.group(0)
                        self._process_match(match, spec_text, pattern_type, result)
                        result['cleaned_text'] = text[:match.start()] + ' ' + text[match.end():]
                        result['cleaned_text'] = re.sub(r'\s+', ' ', result['cleaned_text']).strip()
                        self._standardize_spec(result)
                        return result
        
        # 3. 如果仍未找到，使用原始的通用模式匹配
        for pattern_type, pattern in self.all_patterns:
            match = re.search(pattern, text)
            if match:
                spec_text = match.group(0)
                self._process_match(match, spec_text, pattern_type, result)
                result['cleaned_text'] = text[:match.start()] + ' ' + text[match.end():]
                result['cleaned_text'] = re.sub(r'\s+', ' ', result['cleaned_text']).strip()
                self._standardize_spec(result)
                break
        
        return result
        
    def _process_match(self, match, spec_text, pattern_type, result):
        """处理匹配的规格文本"""
        result['spec_text'] = spec_text
        result['spec_type'] = pattern_type
        
        if pattern_type == 'standard':
            # 标准规格：数字+单位
            value_match = re.search(r'\d+(?:\.\d+)?', spec_text)
            if value_match:
                number = float(value_match.group(0))
                unit = self._extract_unit(spec_text)
                
                result['spec_value'] = number
                result['spec_unit'] = unit
                result['confidence'] = 0.9
        
        elif pattern_type == 'special_L':
            # 特殊处理：小数+L的情况
            number = float(match.group(1))
            result['spec_value'] = number
            result['spec_unit'] = 'L'  # 统一用大写L作为单位
            result['confidence'] = 0.95
        
        elif pattern_type == 'approx':
            # 约数规格："约"+数字+单位
            value_match = re.search(r'\d+(?:\.\d+)?', spec_text)
            if value_match:
                number = float(value_match.group(0))
                unit = self._extract_unit(spec_text)
                
                result['spec_value'] = number
                result['spec_unit'] = unit
                result['confidence'] = 0.85
        
        elif pattern_type == 'range':
            # 范围规格：数字+范围符号+数字+单位
            numbers = re.findall(r'\d+(?:\.\d+)?', spec_text)
            if len(numbers) >= 2:
                # 使用范围的最小值
                result['spec_value'] = float(numbers[0])
                # 记录次要值（范围上限）
                result['secondary_value'] = float(numbers[1])
            elif len(numbers) >= 1:
                result['spec_value'] = float(numbers[0])
            
            unit = self._extract_unit(spec_text)
            result['spec_unit'] = unit
            result['confidence'] = 0.8
        
        elif pattern_type == 'compound':
            # 复合规格：数字+单位+分隔符+数字+单位
            self._process_compound_spec(spec_text, result)
        
        elif pattern_type == 'per_unit':
            # 每单位规格：数字+单位+"每"+单位
            self._process_per_unit_spec(spec_text, result)
    def _extract_unit(self, text: str) -> str:
        """从规格文本中提取单位"""
        for unit in self.sorted_units:
            if unit in text:
                return unit
        return ""
    
    def _process_compound_spec(self, spec_text: str, result: Dict):
        """处理复合规格 (如 500ml*6瓶, 250ml*24盒/箱)"""
        numbers = re.findall(r'\d+(?:\.\d+)?', spec_text)
        units = []
        
        for unit in self.sorted_units:
            if unit in spec_text:
                units.append(unit)
        
        # 特殊处理"/箱"、"*箱"等情况，确保箱被优先考虑
        if '箱' in units:
            # 如果规格文本中包含"/"或"*"，可能是"X单位/箱"或"X单位*箱"的格式
            if ('/' in spec_text and spec_text.endswith('箱')) or spec_text.endswith('箱]') or ('*' in spec_text and '箱' in spec_text) or ('×' in spec_text and '箱' in spec_text) or ('x' in spec_text and '箱' in spec_text):
                # 强制设定箱为主单位
                box_index = units.index('箱')
                if box_index > 0:  # 确保箱不是第一个单位
                    # 调整单位顺序，确保箱是最后一个
                    units.remove('箱')
                    units.append('箱')
                    
                    # 确保数字和单位的对应关系正确
                    if len(numbers) >= len(units):
                        # 如果有足够的数字，使用最后一个数字作为箱数量
                        result['spec_value'] = float(numbers[-1]) if numbers[-1] else 1.0
                        result['spec_unit'] = '箱'
                        
                        # 设置次要值为其他单位对应的值
                        if len(numbers) > 1 and len(units) > 1:
                            result['secondary_value'] = float(numbers[0])
                            result['secondary_unit'] = units[0]
                        else:
                            # 如果数字不足，默认箱数为1
                            result['spec_value'] = 1.0
                            result['spec_unit'] = '箱'
                            
                            if numbers and len(units) > 1:
                                result['secondary_value'] = float(numbers[0])
                                result['secondary_unit'] = units[0]
                        
                        result['confidence'] = 0.95
                        return
        
        # 处理普通的复合规格
        if len(numbers) >= 2 and len(units) >= 2:
            # 确定哪个是主要规格
            first_unit_priority = self.unit_priority.get(units[0], 0)
            second_unit_priority = self.unit_priority.get(units[1], 0)
            
            # 检查是否有更多的单位
            additional_unit_priority = 0
            if len(units) > 2:
                additional_unit_priority = self.unit_priority.get(units[2], 0)
                # 如果第三个单位是箱，且优先级更高，则将其作为主单位
                if units[2] == '箱' or additional_unit_priority > max(first_unit_priority, second_unit_priority):
                    result['spec_value'] = float(numbers[2]) if len(numbers) > 2 else 1.0
                    result['spec_unit'] = units[2]
                    result['secondary_value'] = float(numbers[0])
                    result['secondary_unit'] = units[0]
                    result['confidence'] = 0.95
                    return
            
            if first_unit_priority >= second_unit_priority:
                # 第一个单位优先级更高或相等，将其视为主要规格
                result['spec_value'] = float(numbers[0])
                result['spec_unit'] = units[0]
                result['secondary_value'] = float(numbers[1])
                result['secondary_unit'] = units[1]
            else:
                # 第二个单位优先级更高
                result['spec_value'] = float(numbers[1])
                result['spec_unit'] = units[1]
                result['secondary_value'] = float(numbers[0])
                result['secondary_unit'] = units[0]
            
            result['confidence'] = 0.95  # 复合规格通常更明确
        elif len(numbers) >= 1 and len(units) >= 1:
            # 只有一个规格，按标准处理
            result['spec_value'] = float(numbers[0])
            result['spec_unit'] = units[0]
            result['confidence'] = 0.8
    
    def _process_per_unit_spec(self, spec_text: str, result: Dict):
        """处理每单位规格 (如 500ml每瓶)"""
        numbers = re.findall(r'\d+(?:\.\d+)?', spec_text)
        
        if not numbers:
            return
        
        # 提取单位
        units = []
        parts = spec_text.split("每")
        
        if len(parts) == 2:
            # 第一部分单位
            for unit in self.sorted_units:
                if unit in parts[0]:
                    units.append(unit)
            
            # 第二部分单位
            for unit in self.sorted_units:
                if unit in parts[1]:
                    units.append(unit)
        
        if numbers and units:
            # 按优先级决定主单位
            if len(units) >= 2:
                if self.unit_priority.get(units[1], 0) > self.unit_priority.get(units[0], 0):
                    # 如果"每"后面的单位优先级更高，使用它作为主单位
                    result['spec_value'] = float(numbers[0])
                    result['spec_unit'] = units[1]
                    result['secondary_unit'] = units[0]
                else:
                    # 否则使用第一个单位作为主单位
                    result['spec_value'] = float(numbers[0])
                    result['spec_unit'] = units[0]
                    result['secondary_unit'] = units[1]
            else:
                # 只有一个单位，默认使用
                result['spec_value'] = float(numbers[0])
                result['spec_unit'] = units[0] if units else ""
            
            result['confidence'] = 0.9
    
    def _standardize_spec(self, result: Dict):
        """标准化规格信息 (转换单位和计算标准值)"""
        spec_unit = result['spec_unit']
        spec_value = result['spec_value']
        
        # 没有单位或值，无法标准化
        if not spec_unit or spec_value <= 0:
            return
        
        # 单位转换
        if spec_unit in self.unit_conversion:
            try:
                # 应用转换函数
                standard_value = self.unit_conversion[spec_unit](spec_value)
                
                # 设置标准单位
                if spec_unit in self.standard_unit_map:
                    standard_unit = self.standard_unit_map[spec_unit]
                    result['standard_unit'] = standard_unit
                    result['standard_value'] = standard_value
            except Exception as e:
                logger.warning(f"单位转换失败: {spec_value} {spec_unit}, 错误: {str(e)}")
    
    def extract_specifications_batch(self, df: pd.DataFrame, text_column: str = '商品名称') -> pd.DataFrame:
        """
        批量处理DataFrame中的商品名称，提取规格信息
        
        Args:
            df: 包含商品名称的DataFrame
            text_column: 商品名称列名
            
        Returns:
            添加了规格提取结果的DataFrame
        """
        result_df = df.copy()
        
        # 添加结果列
        new_columns = [
            'specification', 'spec_value', 'spec_unit', 
            'secondary_value', 'secondary_unit',
            'standard_value', 'standard_unit'
        ]
        
        for col in new_columns:
            if col not in result_df.columns:
                if 'value' in col:
                    result_df[col] = 0.0
                else:
                    result_df[col] = ''
        
        # 处理每一行
        for idx, row in df.iterrows():
            text = str(row[text_column]) if not pd.isna(row[text_column]) else ''
            if not text:
                continue
                
            # 提取规格信息
            spec_info = self.extract_specifications(text)
            
            # 更新结果
            result_df.at[idx, 'specification'] = spec_info['spec_text']
            result_df.at[idx, 'spec_value'] = spec_info['spec_value']
            result_df.at[idx, 'spec_unit'] = spec_info['spec_unit']
            result_df.at[idx, 'secondary_value'] = spec_info['secondary_value']
            result_df.at[idx, 'secondary_unit'] = spec_info['secondary_unit']
            result_df.at[idx, 'standard_value'] = spec_info['standard_value']
            result_df.at[idx, 'standard_unit'] = spec_info['standard_unit']
            
            # 更新清洗后的文本
            if 'cleaned_text' in result_df.columns:
                result_df.at[idx, 'cleaned_text'] = spec_info['cleaned_text']
            else:
                result_df['cleaned_text'] = ''
                result_df.at[idx, 'cleaned_text'] = spec_info['cleaned_text']
        
        return result_df
    
    def _process_box_spec(self, text):
        """
        处理整箱装规格信息，包括以下几种格式：
        - 180g*12整箱装
        - 500ml×12箱
        - 330ml*24瓶/箱
        - 200g*10根/箱
        - 200g*10盒/箱
        
        参数:
            text: 商品名称文本
            
        返回:
            处理结果字典或None（如果未找到匹配）
        """
        result = {
            'spec_text': '',
            'spec_type': 'box',
            'spec_value': 0.0,
            'spec_unit': '箱',
            'secondary_value': 0.0, 
            'secondary_unit': '',
            'standard_value': 0.0,
            'standard_unit': '',
            'cleaned_text': text,
            'confidence': 0.95
        }
        
        # 匹配 "数量*单位*数量箱" 或 "数量*单位*数量整箱装" 格式
        box_pattern = rf'(\d+(?:\.\d+)?)\s*(?:{self.units_regex})\s*[*×x]\s*(\d+(?:\.\d+)?)\s*(?:箱|整箱装|整箱)'
        box_match = re.search(box_pattern, text)
        
        # 匹配 "数量*单位*数量瓶/箱" 格式
        bottle_box_pattern = rf'(\d+(?:\.\d+)?)\s*(?:{self.units_regex})\s*[*×x]\s*(\d+(?:\.\d+)?)\s*(?:瓶|个|支|条|罐|包|盒|袋)\s*/\s*箱'
        bottle_box_match = re.search(bottle_box_pattern, text)
        
        if box_match:
            spec_text = box_match.group(0)
            numbers = re.findall(r'\d+(?:\.\d+)?', spec_text)
            
            if len(numbers) >= 2:
                # 提取第一部分的单位（如"500ml"中的"ml"）
                first_part = re.split(r'[*×x]', spec_text)[0]
                unit = self._extract_unit(first_part)
                
                # 设置规格信息
                result['spec_text'] = spec_text
                result['spec_value'] = float(numbers[1])  # 箱数
                result['spec_unit'] = '箱'
                result['secondary_value'] = float(numbers[0])  # 单个商品规格
                result['secondary_unit'] = unit
                
                # 计算总规格值
                total_value = float(numbers[0]) * float(numbers[1])
                result['standard_value'] = total_value
                result['standard_unit'] = unit
                
                # 清理文本
                result['cleaned_text'] = text.replace(spec_text, '').strip()
                result['cleaned_text'] = re.sub(r'\s+', ' ', result['cleaned_text'])
                
                self._standardize_spec(result)
                return result
        
        elif bottle_box_match:
            spec_text = bottle_box_match.group(0)
            numbers = re.findall(r'\d+(?:\.\d+)?', spec_text)
            
            if len(numbers) >= 2:
                # 提取单位信息
                first_part = re.split(r'[*×x]', spec_text)[0]
                unit = self._extract_unit(first_part)
                
                # 提取容器类型（瓶、包等）
                container_type = ''
                for container in ['瓶', '个', '支', '条', '罐', '包', '盒', '袋']:
                    if container in spec_text:
                        container_type = container
                        break
                
                # 设置规格信息
                result['spec_text'] = spec_text
                result['spec_value'] = 1.0  # 默认1箱
                result['spec_unit'] = '箱'
                result['secondary_value'] = float(numbers[0])  # 单个商品规格
                result['secondary_unit'] = unit
                
                # 计算总规格值
                total_value = float(numbers[0]) * float(numbers[1])
                result['standard_value'] = total_value
                result['standard_unit'] = unit
                
                # 清理文本
                result['cleaned_text'] = text.replace(spec_text, '').strip()
                result['cleaned_text'] = re.sub(r'\s+', ' ', result['cleaned_text'])
                
                self._standardize_spec(result)
                return result
                
        # 处理简单的"整箱装"情况
        if '整箱装' in text or '整箱' in text:
            simple_pattern = rf'(\d+(?:\.\d+)?)\s*(?:{self.units_regex})'
            simple_match = re.search(simple_pattern, text)
            
            if simple_match:
                spec_text = simple_match.group(0) + ' 整箱装'
                number = float(re.search(r'\d+(?:\.\d+)?', simple_match.group(0)).group(0))
                unit = self._extract_unit(simple_match.group(0))
                
                # 设置规格信息
                result['spec_text'] = spec_text
                result['spec_value'] = 1.0  # 默认1箱
                result['spec_unit'] = '箱'
                result['secondary_value'] = number  # 单个商品规格
                result['secondary_unit'] = unit
                
                # 清理文本
                box_pos = text.find('整箱')
                if box_pos != -1:
                    box_end = box_pos + (3 if text[box_pos:].startswith('整箱装') else 2)
                    result['cleaned_text'] = text.replace(simple_match.group(0), '').replace(text[box_pos:box_end], '').strip()
                    result['cleaned_text'] = re.sub(r'\s+', ' ', result['cleaned_text'])
                
                self._standardize_spec(result)
                return result
        
        return None

# 简单测试代码
if __name__ == "__main__":
    # 示例单位列表
    test_units = ["g", "kg", "ml", "l", "斤", "千克", "克", "升", "毫升", "包", "袋", "个", "瓶", "盒", "箱"]
    
    # 示例单位转换规则
    test_conversions = {
        "g": lambda x: x / 500,        # 克转斤
        "克": lambda x: x / 500,        # 克转斤
        "kg": lambda x: x * 2,          # 千克转斤
        "千克": lambda x: x * 2,         # 千克转斤
        "斤": lambda x: x,               # 斤保持不变
        "ml": lambda x: x / 1000,       # 毫升转升
        "毫升": lambda x: x / 1000,      # 毫升转升
        "l": lambda x: x,               # 升保持不变
        "升": lambda x: x                # 升保持不变
    }
    
    # 示例标准单位映射
    test_standard_map = {
        "g": "斤", "克": "斤", "kg": "斤", "千克": "斤", "斤": "斤",
        "ml": "升", "毫升": "升", "l": "升", "升": "升"
    }
    
    # 创建规格提取器
    extractor = SpecificationExtractor(test_units, test_conversions, test_standard_map)
    
    # 测试文本
    test_texts = [
        "每日鲜本地油菜 约350g",
        "金龙鱼 大米 5kg装",
        "黄瓜 750g-1kg",
        "饮料 500ml*6瓶整箱",
        "啤酒 330ml每瓶",
        "花生油 1.8L"
    ]
    
    # 测试提取效果
    for text in test_texts:
        result = extractor.extract_specifications(text)
        print(f"原文: {text}")
        print(f"规格文本: {result['spec_text']}, 类型: {result['spec_type']}")
        print(f"规格值: {result['spec_value']} {result['spec_unit']}")
        if result['secondary_value'] > 0:
            print(f"次要规格: {result['secondary_value']} {result['secondary_unit']}")
        if result['standard_value'] > 0:
            print(f"标准化规格: {result['standard_value']} {result['standard_unit']}")
        print(f"清洗后文本: {result['cleaned_text']}")
        print("-" * 40) 